package com.linghang.wusthelper.interceptor;

import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.linghang.wusthelper.annotation.AuthenToken;
import com.linghang.wusthelper.dao.primary.StudentDao;
import com.linghang.wusthelper.entity.primary.Student;
import com.linghang.wusthelper.exception.AuthenException;
import com.linghang.wusthelper.util.JWTUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author origin
 * token认证拦截器
 */
public class AuthenticationIntercaptor implements HandlerInterceptor {

    @Autowired
    StudentDao studentDao;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");     //从请求头中获取token
        //  如果不是映射到方法直接跳过
        if (!(handler instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        Method method = handlerMethod.getMethod();
        //  检查是否有authentoken注解,没有则直接跳过
        if (method.isAnnotationPresent(AuthenToken.class)){
            AuthenToken authenToken = method.getAnnotation(AuthenToken.class);
            if (authenToken.required()){
                //  token为空则为非法请求
                if (token == null){
                    throw new AuthenException("系统权限认证失败");
                }
                String stuNum;
                //  从token中取出stuNum
                try{
                    stuNum = JWT.decode(token).getClaim("stuNum").asString();
                }catch (JWTDecodeException e){
                    throw new AuthenException("token无效");
                }
                Student student = studentDao.selectByStuNum(stuNum);
                if (student == null){
                    throw new AuthenException("用户不存在,请重新登录");
                }
                //  验证token是否有效
                if (JWTUtil.requireToken(token,student)){
                    return true;
                }else {
                    throw new AuthenException("签名无效或已过期");
                }
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
